Hello World
Example of the Cookie CutterThe widget framework is built on top of the Comm framework (short for communication). The Comm framework is a framework that allows you send/receive JSON messages to/from the front end (as seen below).
To create a custom widget, you need to define the widget both in the browser and on the kernel size.
DOMWidget
: Intended to be displayed in the Jupyter notebookWidget
: A terrible name for a synchronized object. It could not have any visual representation._view_name
Inheriting from the DOMWidget does not tell the widget framework what front end widget to associate with your back end widget. Instead, you must tell it yourself by defining a specially named traitlet, _view_name
(as seen below).
In [1]:
import ipywidgets as widgets
from traitlets import Unicode
class HelloWidget(widgets.DOMWidget):
_view_name = Unicode('HelloView').tag(sync=True)
_view_module = Unicode('hello').tag(sync=True)
Jupyter widgets rely on Backbone.js.
Backbone.js is an MVC (model view controller) framework.
Widgets defined in the back end are automatically synchronized with generic Backbone.js models in the front end. The traitlets are added to the front end instance automatically on first state push. The _view_name
trait that you defined earlier is used by the widget framework to create the corresponding Backbone.js view and link that view to the model.
In [2]:
%%javascript
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
var HelloView = widgets.DOMWidgetView.extend({
// Render the view.
render: function() {
this.$el.text('Hello World!');
},
});
return {
HelloView: HelloView
};
});
You should be able to display your widget just like any other widget now.
In [3]:
HelloWidget()
Instead of displaying a static "hello world" message, we can display a string set by the back end.
First you need to add a traitlet in the back end.
(Use the name of value
to stay consistent with the rest of the widget framework and to allow your widget to be used with interact.)
In [4]:
class HelloWidget(widgets.DOMWidget):
_view_name = Unicode('HelloView').tag(sync=True)
_view_module = Unicode('hello').tag(sync=True)
value = Unicode('Hello World!').tag(sync=True)
In [5]:
%%javascript
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
var HelloView = widgets.DOMWidgetView.extend({
render: function() {
this.$el.text(this.model.get('value'));
},
});
return {
HelloView : HelloView
};
});
In [6]:
%%javascript
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
var HelloView = widgets.DOMWidgetView.extend({
render: function() {
this.value_changed();
this.model.on('change:value', this.value_changed, this);
},
value_changed: function() {
this.$el.text(this.model.get('value'));
},
});
return {
HelloView : HelloView
};
});
In [7]:
w = HelloWidget()
w
In [8]:
w.value = 'test'
In [9]:
from traitlets import CInt
class SpinnerWidget(widgets.DOMWidget):
_view_name = Unicode('SpinnerView').tag(sync=True)
_view_module = Unicode('spinner').tag(sync=True)
value = CInt().tag(sync=True)
In [10]:
%%javascript
requirejs.undef('spinner');
define('spinner', ["@jupyter-widgets/base"], function(widgets) {
var SpinnerView = widgets.DOMWidgetView.extend({
render: function() {
var that = this;
this.$input = $('<input />');
this.$el.append(this.$input);
this.$spinner = this.$input.spinner({
change: function( event, ui ) {
that.handle_spin(that.$spinner.spinner('value'));
},
spin: function( event, ui ) {
//ui.value is the new value of the spinner
that.handle_spin(ui.value);
}
});
this.value_changed();
this.model.on('change:value', this.value_changed, this);
},
value_changed: function() {
this.$spinner.spinner('value', this.model.get('value'));
},
handle_spin: function(value) {
this.model.set('value', value);
this.touch();
},
});
return {
SpinnerView: SpinnerView
};
});
In [11]:
w = SpinnerWidget(value=5)
w
In [12]:
w.value = 7
In [13]:
from IPython.display import display
w1 = SpinnerWidget(value=0)
w2 = widgets.IntSlider()
display(w1,w2)
from traitlets import link
mylink = link((w1, 'value'), (w2, 'value'))
In [ ]:
In [ ]:
In [ ]:
In [ ]: